package org.bdware.irs.backend.servicesImpl;

import org.bdware.irs.backend.services.StateInfoCodec;
import org.bdware.irs.backend.services.StateInfoStorage;
import org.bdware.irs.backend.utils.StateInfoCodecImpl;
import org.apache.log4j.Logger;
import org.bdware.irp.stateinfo.StateInfoBase;
import org.rocksdb.Options;
import org.rocksdb.RocksDB;
import org.rocksdb.RocksDBException;

import java.io.File;
import java.io.IOException;

public class StateInfoStorageRocksDBImpl implements StateInfoStorage {


    static Logger logger = Logger.getLogger(StateInfoStorageRocksDBImpl.class);
    RocksDB db;
    String dbPath;
    StateInfoCodec siCodec = new StateInfoCodecImpl();
    IRHelperServiceImpl irHelperServiceImpl = new IRHelperServiceImpl();

    static {
        RocksDB.loadLibrary();
    }

    public StateInfoStorageRocksDBImpl(String dbPath){
        this.dbPath = dbPath;
        Options rockOpts = new Options().setCreateIfMissing(true);
        try {
            logger.debug("rocksdb data path for irs: " + new File(dbPath).getAbsolutePath());
            db = RocksDB.open(rockOpts, dbPath);
        } catch (RocksDBException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    public StateInfoStorageRocksDBImpl(){
        this("./rocksdb_irs/");
    }


    protected RocksDB getDBInstance(){
        return db;
    }

    @Override
    public StateInfoBase getStateInfoByID(String id) {
        StateInfoBase stateInfo = null;
        try {
            byte[] infoBytes = db.get(id.getBytes());
            if(infoBytes == null)
                return null;
            stateInfo = siCodec.ByteArrayToStateInfo(infoBytes);
        } catch (RocksDBException | IOException e) {
            e.printStackTrace();
        } finally{
            return stateInfo;
        }

    }

    @Override
    public boolean saveStateInfo(StateInfoBase stateInfo) {
        try {
            db.put(stateInfo.getIdentifier().getBytes(),siCodec.StateInfoToByteArray(stateInfo));
        } catch (RocksDBException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    //没有doi的时候的创建方法，会返回分配的doi号
    @Override
    public String createStateInfo(StateInfoBase stateInfo, String type) {
        String doi = irHelperServiceImpl.doiGenerator(type);
        stateInfo.setIdentifier(doi);
        try {
            db.put(stateInfo.getIdentifier().getBytes(),siCodec.StateInfoToByteArray(stateInfo));
        } catch (RocksDBException e) {
            doi = null;
            e.printStackTrace();
        } finally {
            return doi;
        }
    }

    @Override
    public boolean deleteStateInfoByID(String id) {
        try {
            db.delete(id.getBytes());
        } catch (RocksDBException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    @Override
    public StateInfoBase updateStateInfo(StateInfoBase stateInfo) {
        System.out.println("=====delete=====");
        deleteStateInfoByID(stateInfo.getIdentifier());
        System.out.println("=====save=====");
        saveStateInfo(stateInfo);
        return stateInfo;
    }
}
